﻿#pragma once
#include <QObject>
#include <QVector>
#include <QMap>
#include <QList>

template <class T>
class KGroupVectorPtrT : public QObject
{
	//Q_OBJECT
protected:
	typedef QVector<T*> ARRAY;
	QVector<T*>  group;
	bool lock_flag;
public:
	KGroupVectorPtrT(QObject*parent = nullptr) :QObject(parent),lock_flag(false) {}
	virtual ~KGroupVectorPtrT() {}

public:
	bool locked() {
		return lock_flag;
	}
	void setLocked(bool v)
	{
		lock_flag = v;
	}

	int count()
	{
		return group.count();
	}
	QVector<T*>*items()
	{
		return &group;
	}
	T* item(int idx)
	{
		if (idx < 0 || idx >= group.count())
			return nullptr;

		return group[idx];
	}
	int idxOf(const T*key)
	{
		int i = 0;
		ARRAY::const_iterator itr = group.constBegin();
		for (; itr != group.constEnd(); itr++) {
			if (*itr == key)
				return i;
			i++;
		}
		return -1;
	}

	void addItem(T* ptr)
	{
		group.append(ptr);
	}
	void delItem(int idx, bool to_free = true)
	{
		T* p = item(idx);
		if (!p)
			return;
		if (to_free)
			delete p;
		group.remove(idx);
	}
	T* takeItem(int idx)
	{
		T* p = item(idx);
		if (p) {
			group.remove(idx);
		}
		return p;
	}
	void delItem(const T*ptr, bool to_free = true)
	{
		ARRAY::iterator itr = group.begin();
		for (; itr != group.end(); itr++) {
			if (*itr == ptr)
			{
				group.erase(itr);
				if (to_free)
						delete ptr;
				break;
			}
		}
	}

	void clear()
	{
		for each(auto a in group)
			delete a;
		group.clear();
	}
};

template <class KEY, class T>
class KGroupMapPtrT : public QObject
{
protected:
	typedef QMap<KEY, T*> GROUP;
	QMap<KEY, T*> group;
	bool lock_flag;
public:
	KGroupMapPtrT(QObject *parent = nullptr):QObject(parent),lock_flag(false){}
	virtual ~KGroupMapPtrT(){}

	bool locked() {
		return lock_flag;
	}
	void setLocked(bool v)
	{
		lock_flag = v;
	}

	QMap<KEY, T*>*items()
	{
		return &group;
	}

	T* item(const KEY&key)
	{
		QMap<KEY, T*>::const_iterator itr = group.find(key);
		if (itr == group.end())
			return nullptr;

		return itr.value();
	}
	QList< KEY> keys()
	{
		return group.keys();
	}
	int count()
	{
		return group.count();
	}

	void setItem(const KEY&key, T*val)
	{
		group[key] = val;
	}
	void remove(const KEY&key)
	{
		group.remove(key);
	}
	void delItem(const KEY&key)
	{
		GROUP::iterator itr = group.find(key);
		if (itr == group.end())
			return;

		delete itr.value();
		group.erase(itr);
	}
	void clear()
	{
		for each(auto a in group) {
			delete a;
		}
		group.clear();
	}
};

template <class KEY, class T>
class KGroupPtrT : public QObject
{
public:
	typedef QMap<KEY, T*> GROUP;
	typedef QVector<KEY> ARRAY;
protected:
	QMap<KEY, T*> group;
	QVector<KEY> array;
	bool lock_flag;
public:
	KGroupPtrT(QObject *parent = nullptr) :QObject(parent), lock_flag(false) {}
	virtual ~KGroupPtrT() {}

	bool locked() {
		return lock_flag;
	}
	void setLocked(bool v)
	{
		lock_flag = v;
	}

	QMap<KEY, T*>*items()
	{
		return &group;
	}

	T* item(const KEY&key)
	{
		QMap<KEY, T*>::const_iterator itr = group.find(key);
		if (itr == group.end())
			return nullptr;

		return itr.value();
	}
	T* item(int idx)
	{
		if (idx < 0 || idx >= array.count())
			return nullptr;

		return item(array[idx]);
	}
	KEY keyAt(int idx)
	{
		if (idx < 0 || idx >= array.count())
			return KEY();
		return array[idx];
	}
	int idxOf(const KEY&key)
	{
		int i = 0;
		ARRAY::const_iterator itr = array.constBegin();
		for (; itr != array.constEnd(); itr++) {
			if (itr == key)
				return i;
			i++;
		}
		return -1;
	}
	QVector< KEY>& keys()
	{
		return array;//group.keys();
	}
	int count()
	{
		return array.count();
	}

	void setItem(const KEY&key, T*val)
	{
		QMap<KEY, T*>::const_iterator itr = group.find(key);
		if (itr == group.end()) {
			array.append(key);
			group[key] = val;
		}
		else {
			group[key] = val;
		}
	}
	void delItem(const KEY&key)
	{
		GROUP::iterator itr = group.find(key);
		if (itr == group.end())
			return;

		delete itr.value();
		group.erase(itr);
		array.removeOne(key);
	}
	void clear()
	{
		for each(auto a in group) {
			delete a;
		}
		group.clear();
		array.clear();
	}
};
